package com.yj.question_project.question;

import com.alibaba.fastjson2.JSON;
import com.yj.question_project.domain.MetroLine;
import com.yj.question_project.domain.R;
import com.yj.question_project.domain.VNode;
import com.yj.question_project.service.Ques4Service;
import com.yj.question_project.utils.NodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Auther: starsky1
 * @Date: 2024/01/11 17:08
 * @Description: todo
 */
@RestController
@RequestMapping("/ques4/")
@Slf4j
public class Ques4 {
    @Autowired
    private Ques4Service ques4Service;

    private static Map<Integer, VNode> stationMap = new HashMap<>(50);
    private static Map<String, Integer> stationIdMap = new HashMap<>(50);
    private static Map<String, MetroLine> lineMap = new HashMap<>(20);
    private static int min;

    @PostConstruct
    public void init() {
        NodeUtils.initData(stationMap, stationIdMap, lineMap);
    }

    public List<List<VNode>> getAllPaths(Integer start, Integer end) {
        min = Integer.MAX_VALUE;
        List<List<VNode>> paths = new ArrayList<>();
        List<VNode> path = new ArrayList<>();
        path.add(stationMap.get(start));
        dfs(stationMap.get(start), end, new HashSet<>(), path, paths);
        return paths;
    }

    public void dfs(VNode curr, int end, Set<Integer> visited,
                           List<VNode> path, List<List<VNode>> paths) {
        if(curr == null) {
            return;
        }
        if(curr.getStaId() == end) {
            paths.add(new ArrayList<>(path));
            min = Math.min(min, path.size());
            return;
        }
        for (VNode neighbor : curr.getRelateNodes()) {
            if(!visited.contains(neighbor.getStaId())) {
                if(path.size()+1>min) {
                    return;
                }
                path.add(neighbor);
                visited.add(neighbor.getStaId());
                dfs(neighbor, end, visited, path, paths);
                path.remove(path.size()-1);
                visited.remove(neighbor.getStaId());
            }
        }
    }

    /**
     * 用于 vue 作地铁图
     *
     * @return 所有节点坐标信息
     */
    @GetMapping("/getAllVNode")
    public R getAllVNode() {
        return R.ok().data(ques4Service.selectAllVNode());
    }

    @GetMapping(value = "/getAllEdges")
    public R getAllEdges() {
        return R.ok().data(ques4Service.selectAllEdges());
    }

    @PostMapping(value = "/findPaths")
    public R findPaths(@RequestParam Integer startId,
                       @RequestParam Integer endId) {
        List<List<VNode>> paths = getAllPaths(startId, endId);
        paths = paths.stream().filter(path -> path.size()<=min).collect(Collectors.toList());
        List<List<Integer>> ids = paths.stream()
                .map(path -> path.stream().map(node -> node.getStaId()).collect(Collectors.toList()))
                .collect(Collectors.toList());
        return R.ok().data(ids);
    }
}
